package com.hzw.saas.common.config.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.hzw.saas.common.config.exception.DefaultSaasException;
import com.hzw.saas.common.util.enums.AssertEnum;
import com.hzw.saas.common.util.exception.ConflictException;
import com.hzw.saas.common.util.exception.LostException;
import com.hzw.saas.common.util.exception.NotFoundException;
import org.springframework.http.HttpStatus;

import java.util.Objects;

public class AssertUtil {

    public static void assertThrow(String msg, boolean condition) {
        assertThrowException(condition, DefaultSaasException.build(msg).status(HttpStatus.BAD_REQUEST));
    }

    public static void assertThrow(String msg, HttpStatus httpStatus, boolean condition) {
        assertThrowException(condition, DefaultSaasException.build(msg).status(httpStatus));
    }

    public static void assertThrow(String msg, Throwable throwable, boolean condition) {
        assertThrowException(condition, DefaultSaasException.build(msg, throwable));
    }

    public static void assertThrowException(boolean condition, RuntimeException e) {
        if(condition) {
            throw e;
        }
    }

    /**
     * @param assertEnum   断言结果
     * @param actualResult 实际结果
     * @param resultName   结果实体名称
     * @throws ConflictException 数据冲突
     * @throws NotFoundException 未找到，请求错误
     * @throws LostException     数据丢失，服务器端错误
     */
    public static void assertBoolean(AssertEnum assertEnum, boolean actualResult, String resultName) throws ConflictException, NotFoundException, LostException {
        // 不进行断言
        if (ignore(assertEnum)) return;
        // 断言正确
        if (Objects.equals(assertEnum.getAssertResult(), actualResult)) return;
        // 断言错误
        String errorMsg = StrUtil.concat(true, resultName, assertEnum.getErrorMsg());
        if (actualResult) {
            // data conflict (request error)
            throw new ConflictException(errorMsg);
        }
        if (Objects.equals(assertEnum, AssertEnum.EXIST)) {
            // data lost (server error)
            throw new LostException(errorMsg);
        } else {
            // data not found (request error)
            throw new NotFoundException(errorMsg);
        }
    }

    /**
     * @param assertEnum      断言结果
     * @param actualResultObj 实际结果，对象为空(null,string,Map,Iterable,Iterator,Array) = false
     * @param resultName      结果实体名称
     * @throws ConflictException 数据冲突
     * @throws NotFoundException 未找到，请求错误
     * @throws LostException     数据丢失，服务器端错误
     */
    public static void assertExistence(AssertEnum assertEnum, Object actualResultObj, String resultName) throws ConflictException, NotFoundException, LostException {
        if (ignore(assertEnum)) return;
        boolean actualResult = ObjectUtil.isNotEmpty(actualResultObj);
        assertBoolean(assertEnum, actualResult, resultName);
    }

    private static boolean ignore(AssertEnum assertEnum) {
        return Objects.isNull(assertEnum) || Objects.equals(assertEnum, AssertEnum.IGNORE);
    }

}
